{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "76e89c57",
   "metadata": {},
   "source": [
    "# DAY 25 \n",
    "\n",
    "相信大家在借助ai写代码的时候，经常会遇到try-except的异常处理模块，这是因为大部分大模型在后训练阶段都是经过强化学习训练的，为了确保结果的正确运行，只有采取 try-except的异常处理模块才能提高模型运行成功的概率。\n",
    "\n",
    "但是我们日常写代码的时候，大概率不会采取这些写法。所以我们要适应ai的写法。\n",
    "\n",
    "这也是今天专题的由来"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "96e37b69",
   "metadata": {},
   "source": [
    "## 异常处理机制"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2597d53f",
   "metadata": {},
   "source": [
    "Python的异常处理机制为程序提供了强大的容错能力 (fault tolerance)。当程序在运行时遇到意外情况（即异常），它不会直接崩溃，而是可以被设计成优雅地处理这些错误，并可能继续执行后续逻辑（如果设计允许）或以可控的方式结束。\n",
    "\n",
    "当异常发生时，Python会创建一个异常对象 (exception object)（通常是 Exception 类的子类实例）。如果这段可能出错的代码位于 try 语句块中，程序流程会寻找并跳转到匹配的 except 语句块（如果存在）来处理这个异常。\n",
    "\n",
    "核心概念：\n",
    "\n",
    "- try: 包含可能会引发异常的代码块。程序会首先尝试执行这里的代码。\n",
    "- except: 如果try块中的代码确实引发了特定类型的异常（或者任何异常，如果未指定类型），则执行此代码块。\n",
    "- else: （可选）如果try块中的代码没有发生任何异常，则执行此代码块。\n",
    "- finally: （可选）无论try块中是否发生异常，总会执行此代码块（常用于资源清理）。\n",
    "\n",
    "常见语句结构如下：\n",
    "\n",
    "1. try-except\n",
    "\n",
    "这是最基本的错误处理结构。\n",
    "\n",
    "```python\n",
    "try:\n",
    "    # 可能会引发异常的代码\n",
    "except ExceptionType: # 最好指定具体的异常类型，例如 ZeroDivisionError, FileNotFoundError\n",
    "    # 当 try 块中发生 ExceptionType 类型的异常时执行的代码\n",
    "except: # 不推荐：捕获所有类型的异常，可能会隐藏bug\n",
    "    # 当 try 块中发生任何其他未被前面 except 捕获的异常时执行的代码\n",
    "```\n",
    "\n",
    "逻辑说明： 程序首先尝试执行 try 块中的代码。\n",
    "\n",
    "如果 try 块中的代码没有发生异常，则 except 块会被跳过，程序继续执行 try-except 结构之后的代码。\n",
    "\n",
    "如果 try 块中的代码发生了异常，Python会查找与该异常类型匹配的 except 块。如果找到匹配的，则执行该 except 块中的代码，然后继续执行整个 try-except 结构之后的代码（除非 except 块中又引发了新异常或执行了 return/break/continue 等）。如果未找到匹配的 except 块，异常会向上传播。\n",
    "\n",
    "类比： 你可以把它看作是：“尝试做这件事，如果出错了（并且是特定类型的错误），就执行补救措施。”\n",
    "\n",
    "1. try-except-else\n",
    "\n",
    "在 try-except 的基础上增加了 else 子句。\n",
    "\n",
    "```python\n",
    "try:\n",
    "    # 可能会引发异常的代码\n",
    "except ExceptionType:\n",
    "    # 当 try 块中发生 ExceptionType 类型的异常时执行的代码\n",
    "else:\n",
    "    # 当 try 块中【没有】发生任何异常时执行的代码\n",
    "```\n",
    "\n",
    "逻辑说明：\n",
    "首先，执行 try 块中的代码。\n",
    "\n",
    "如果 try 块中发生异常，则会查找并执行匹配的 except 块，else 块不会被执行。\n",
    "\n",
    "如果 try 块中没有发生任何异常，则会跳过所有 except 块，然后执行 else 块中的代码。\n",
    "\n",
    "**与 if-else-elif 的区别（重要！）：**\n",
    "\n",
    "if-elif-else 结构中，只有一个代码块会被执行（if 条件满足则执行 if 块；否则检查 elif，满足则执行 elif 块；否则执行 else 块）。\n",
    "\n",
    "而在 try-except-else 结构中：\n",
    "\n",
    "如果 try 成功：try 块的代码会执行，然后 else 块的代码也会执行。\n",
    "\n",
    "如果 try 失败：try 块中出错前的代码会执行，然后匹配的 except 块的代码会执行（else 块不会执行）。\n",
    "\n",
    "更准确的理解： else 子句中的代码是你希望在 try 块中的代码成功完成且没有引发任何异常之后才执行的代码。这通常用于分离“主要尝试的操作”和“操作成功后的后续步骤”，使得 try 块更聚焦于可能出错的部分。\n",
    "\n",
    "一个简单的例子阐述 else 的作用：\n",
    "\n",
    "```python\n",
    "try:\n",
    "    # 假设 result_operation() 是一个可能出错的操作\n",
    "    value = result_operation()\n",
    "except SomeError:\n",
    "    print(\"操作失败，使用默认值。\")\n",
    "    value = default_value\n",
    "else:\n",
    "    # 只有当 result_operation() 成功时，才执行这里的代码\n",
    "    print(f\"操作成功，结果是: {value}。现在进行后续处理...\")\n",
    "    process_value_further(value)\n",
    "\n",
    "\n",
    "如果把 process_value_further(value) 放在 try 块内，那么如果 process_value_further 本身也可能抛出 SomeError（或其他 try 块想要捕获的错误），它就会被意外捕获。else 块确保了只有在 try 块中的代码完全无误地执行完毕后，才会执行 else 块的内容。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "54d52f60",
   "metadata": {},
   "source": [
    "下面我们来介绍下有哪些异常报错，如果你留心报错信息，常见以下几种：\n",
    "\n",
    "值得一提的是，过去"
   ]
  },
  {
   "attachments": {
    "image.png": {
     "image/png": "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"
    }
   },
   "cell_type": "markdown",
   "id": "5ed167bb",
   "metadata": {},
   "source": [
    "![image.png](attachment:image.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d9d0b22d",
   "metadata": {},
   "source": [
    "## debug\n",
    "\n",
    "过去ai没有兴起的时候，debug主要靠搜索解决方案+理解报错信息，现在很多人直接借助ai就可以无脑解决，实际上这又回到我们最初的观点：此时你的能力并没有提升。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2fd0bd4c",
   "metadata": {},
   "source": [
    "### SyntaxError (语法错误)\n",
    "\n",
    "原因： 代码不符合 Python 的语法规则，解释器在尝试解析代码时就会失败。这种错误在程序 运行之前 就会被检测到。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "39d0a96f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "--- 1. SyntaxError ，可取消下列注释运行查看---\n"
     ]
    }
   ],
   "source": [
    "print(\"--- 1. SyntaxError ，可取消下列注释运行查看---\")\n",
    "# 示例 a: 缺少冒号\n",
    "# def my_function()\n",
    "#     print(\"Hello\")\n",
    "\n",
    "\n",
    "# 示例 b: 非法表达式\n",
    "# x = 5 +\n",
    "# print(x)\n",
    "\n",
    "# 为了让脚本能继续运行其他示例，我会注释掉这些会直接导致脚本无法解析的错误\n",
    "# 请在演示时逐个取消注释并运行，观察错误"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6c3841dc",
   "metadata": {},
   "source": [
    "### NameError (名称错误)\n",
    "\n",
    "原因： 尝试使用一个未被定义的变量、函数或对象的名称。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "375dbe6f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 示例 a: 变量未定义\n",
    "# print(some_undefined_variable)\n",
    "\n",
    "# 示例 b: 打错变量名\n",
    "# print(my_lisst) # 变量名拼写错误"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "38341b9b",
   "metadata": {},
   "source": [
    "### TypeError (类型错误)\n",
    "\n",
    "原因： 对一个不支持该操作的数据类型执行了某个操作或函数。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "80e3b1bb",
   "metadata": {},
   "outputs": [],
   "source": [
    "# print(\"Age: \" + 25) # 字符串和整数\n",
    "# my_number = 10\n",
    "# my_number() # 尝试像函数一样调用一个整数"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "98e7f7e1",
   "metadata": {},
   "source": [
    "### ValueError (值错误)\n",
    "\n",
    "原因： 函数接收到的参数类型正确，但其值不合适或无效。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "86246ad9",
   "metadata": {},
   "outputs": [],
   "source": [
    "# my_string = \"12.34.56\"\n",
    "# number = float(my_string) # '12.34.56' 不是一个有效的浮点数表示"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "308621b5",
   "metadata": {},
   "source": [
    "### IndexError (索引错误)\n",
    "\n",
    "原因： 尝试访问序列（如列表、元组、字符串）中一个不存在的索引。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "7506afd0",
   "metadata": {},
   "outputs": [],
   "source": [
    "# data = (\"apple\", \"banana\")\n",
    "# print(data[2])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2f65c1a1",
   "metadata": {},
   "source": [
    "### KeyError (键错误)\n",
    "\n",
    "原因： 尝试访问字典中一个不存在的键。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e8cbeef4",
   "metadata": {},
   "outputs": [],
   "source": [
    "# student_grades = {\"math\": 90, \"science\": 85}\n",
    "# print(student_grades[\"history\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "eeed0af3",
   "metadata": {},
   "source": [
    "### AttributeError (属性错误)\n",
    "\n",
    "原因： 尝试访问一个对象没有的属性或方法。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "269e46e7",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 示例a\n",
    "# a_string = \"hello\"\n",
    "# print(a_string.length) # 字符串长度用 len(a_string)，不是 .length 属性\n",
    "\n",
    "# 示例b\n",
    "# import numpy as np\n",
    "# arr = np.array([1,2,3])\n",
    "# print(arr.non_existent_attribute)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4a3563ca",
   "metadata": {},
   "source": [
    "今天过后，每次执行代码 可以简单看看代码报错信息，而不是总是无脑交给ai来解决，给自己成长的空间"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6cd04e93",
   "metadata": {},
   "source": [
    "### ZeroDivisionError (除零错误)\n",
    "\n",
    "原因： 尝试将一个数字除以零。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "0372a1ee",
   "metadata": {},
   "outputs": [],
   "source": [
    "# result = 10 / 0\n",
    "# result"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d584ae1f",
   "metadata": {},
   "source": [
    "### FileNotFoundError (文件未找到错误)\n",
    "\n",
    "原因： 尝试打开一个不存在的文件（通常是在读模式下），或者路径不正确。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "d6af32ae",
   "metadata": {},
   "outputs": [],
   "source": [
    "# import pandas as pd\n",
    "# data = pd.read_csv(\"hh.csv\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bc3b697a",
   "metadata": {},
   "source": [
    "###  ModuleNotFoundError (导入错误)\n",
    "\n",
    "尝试导入一个不存在的模块，或者模块存在但其中的特定名称找不到， Python 的模块加载器找不到这个模块。去安装库即可，如果是自定义的模块，配置好对应的路径"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "39934374",
   "metadata": {},
   "outputs": [],
   "source": [
    "# import hhh"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2e985d20",
   "metadata": {},
   "source": [
    "已经看到，当你的代码出现这类错误时，程序会立即停止执行，并打印出一个 “traceback”（回溯信息），这个信息非常重要，它会告诉你：\n",
    "1. 错误类型 (e.g., NameError, TypeError)\n",
    "2. 错误发生的文件名和行号\n",
    "3. 导致错误的那行代码\n",
    "4. 错误的简要描述\n",
    "\n",
    "接下来来用固定的语句捕获这类错误"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5edce20d",
   "metadata": {},
   "source": [
    "##  try-except\n",
    "\n",
    "try：把你认为可能会出错的代码放在这里。\n",
    "\n",
    "except：如果 try 块里的代码真的出错了（从出错开始就不会继续执行try之后的代码了），Python 就会跳到 except 块里执行这里的代码，而不是崩溃。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "dd7e9b35",
   "metadata": {},
   "outputs": [
    {
     "ename": "ZeroDivisionError",
     "evalue": "division by zero",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mZeroDivisionError\u001b[0m                         Traceback (most recent call last)",
      "Cell \u001b[1;32mIn[32], line 4\u001b[0m\n\u001b[0;32m      2\u001b[0m numerator \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m10\u001b[39m\n\u001b[0;32m      3\u001b[0m denominator \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m0\u001b[39m\n\u001b[1;32m----> 4\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[43mnumerator\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m/\u001b[39;49m\u001b[43m \u001b[49m\u001b[43mdenominator\u001b[49m \u001b[38;5;66;03m# 这行会引发 ZeroDivisionError\u001b[39;00m\n\u001b[0;32m      5\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m结果是: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mresult\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m      6\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m这行代码不会执行，因为程序已崩溃\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n",
      "\u001b[1;31mZeroDivisionError\u001b[0m: division by zero"
     ]
    }
   ],
   "source": [
    "# print(\"--- 之前会崩溃的代码 (ZeroDivisionError) ---\")\n",
    "numerator = 10\n",
    "denominator = 0\n",
    "result = numerator / denominator # 这行会引发 ZeroDivisionError\n",
    "print(f\"结果是: {result}\")\n",
    "print(\"这行代码不会执行，因为程序已崩溃\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "59faff39",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "--- 使用 try-except 捕获 ZeroDivisionError ---\n",
      "尝试进行除法运算...\n",
      "发生了一个除以零的错误！\n",
      "程序继续执行... 最终结果的记录为: 未定义 (除以零)\n"
     ]
    }
   ],
   "source": [
    "print(\"--- 使用 try-except 捕获 ZeroDivisionError ---\")\n",
    "numerator = 10\n",
    "denominator = 0\n",
    "\n",
    "try:\n",
    "    print(\"尝试进行除法运算...\")\n",
    "    result = numerator / denominator # 潜在的风险代码\n",
    "    print(f\"计算结果是: {result}\") # 如果上面出错，这行不会执行\n",
    "except ZeroDivisionError:\n",
    "    print(\"发生了一个除以零的错误！\")\n",
    "    result = \"未定义 (除以零)\" # 可以给一个默认值或提示\n",
    "\n",
    "print(f\"程序继续执行... 最终结果的记录为: {result}\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "6d7476dd",
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "can only concatenate str (not \"int\") to str",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "Cell \u001b[1;32mIn[36], line 4\u001b[0m\n\u001b[0;32m      2\u001b[0m x \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mhello\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m      3\u001b[0m y \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m5\u001b[39m\n\u001b[1;32m----> 4\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[43mx\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m+\u001b[39;49m\u001b[43m \u001b[49m\u001b[43my\u001b[49m \u001b[38;5;66;03m# 字符串不能和整数直接相加\u001b[39;00m\n\u001b[0;32m      5\u001b[0m \u001b[38;5;28mprint\u001b[39m(result)\n",
      "\u001b[1;31mTypeError\u001b[0m: can only concatenate str (not \"int\") to str"
     ]
    }
   ],
   "source": [
    "# print(\"--- 之前会崩溃的代码 (TypeError) ---\")\n",
    "x = \"hello\"\n",
    "y = 5\n",
    "result = x + y # 字符串不能和整数直接相加\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "b06dba0d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "--- 使用 try-except 捕获 TypeError ---\n",
      "尝试连接字符串和数字...\n",
      "类型错误！不能直接将字符串和数字相加。\n",
      "尝试将数字转换为字符串进行连接...\n",
      "修正后的消息: Total items: 5\n",
      "程序继续... 生成的消息是: Total items: 5\n"
     ]
    }
   ],
   "source": [
    "print(\"--- 使用 try-except 捕获 TypeError ---\")\n",
    "x = \"Total items: \"\n",
    "y = 5 # 假设这是一个从某处获取的数字\n",
    "\n",
    "try:\n",
    "    print(\"尝试连接字符串和数字...\")\n",
    "    message = x + y # 潜在的 TypeError\n",
    "    print(f\"最终消息: {message}\")\n",
    "except TypeError:\n",
    "    print(\"类型错误！不能直接将字符串和数字相加。\")\n",
    "    print(\"尝试将数字转换为字符串进行连接...\")\n",
    "    message = x + str(y) # 修正操作\n",
    "    print(f\"修正后的消息: {message}\")\n",
    "\n",
    "print(f\"程序继续... 生成的消息是: {message}\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e9d802fd",
   "metadata": {},
   "source": [
    "接下来，我们可以讨论如何捕获多种类型的错误，以及 else 和 finally 子句的用法。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "09c7f7c4",
   "metadata": {},
   "source": [
    "## try - except- else -fiinally\n",
    "- try: 包含可能引发异常的代码。\n",
    "- except: 处理在 try 块中发生的特定异常。\n",
    "- else: （可选）如果 try 块中没有发生任何异常，则执行此代码块。\n",
    "- finally: （可选）无论 try 块中是否发生异常，总会执行此代码块。\n",
    "\n",
    "为什么使用 else？\n",
    "1. 清晰性： 它清楚地将“主要尝试的操作（可能出错）”与“操作成功后的后续步骤”分开。\n",
    "2. 避免意外捕获： 如果把“成功后的后续步骤”也放在 try 块里，而这些步骤本身也可能引发 try 块想要捕获的同类型异常，那么就会导致逻辑混淆。else 块中的代码不会被同一个 try 块的 except 子句捕获。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "a5f14f06",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "--- try-except-else 示例 ---\n",
      "\n",
      "尝试计算 10 / 2\n",
      "除法运算成功！\n",
      "结果是: 5.0\n",
      "结果的两倍是: 10.0\n",
      "\n",
      "尝试计算 10 / 0\n",
      "错误：除数不能为零！\n",
      "\n",
      "尝试计算 10 / 2\n",
      "错误：输入必须是数字！\n",
      "\n",
      "尝试计算 20 / abc\n",
      "错误：输入必须是数字！\n"
     ]
    }
   ],
   "source": [
    "print(\"--- try-except-else 示例 ---\")\n",
    "\n",
    "def safe_divide(a, b):\n",
    "    print(f\"\\n尝试计算 {a} / {b}\")\n",
    "    try:\n",
    "        result = a / b\n",
    "    except ZeroDivisionError:\n",
    "        print(\"错误：除数不能为零！\")\n",
    "        return None # 或者其他表示失败的值\n",
    "    except TypeError:\n",
    "        print(\"错误：输入必须是数字！\")\n",
    "        return None\n",
    "    else:\n",
    "        # 只有当 try 块中的 a / b 成功执行时，这里才会执行\n",
    "        print(\"除法运算成功！\")\n",
    "        print(f\"结果是: {result}\")\n",
    "        # 可以在这里进行基于成功结果的进一步操作\n",
    "        print(f\"结果的两倍是: {result * 2}\")\n",
    "        return result\n",
    "\n",
    "# 测试用例\n",
    "safe_divide(10, 2)  # 成功\n",
    "safe_divide(10, 0)  # ZeroDivisionError\n",
    "safe_divide(\"10\", 2) # TypeError (如果我们不先做类型转换的话)\n",
    "safe_divide(20, \"abc\") # TypeError"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bcd94f7c",
   "metadata": {},
   "source": [
    "上述写法可以使函数更加健壮，实现同样的逻辑可以最开始使用if else 判断输入格式"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "25c8f0e7",
   "metadata": {},
   "source": [
    "finally 子句\n",
    "finally 子句中的代码无论 try 块中是否发生异常，也无论 except 块是否被执行，甚至无论 try 或 except 块中是否有 return 语句，它总会被执行。\n",
    "\n",
    "finally这个无论如何都会执行的特性，在机器学习和深度学习的中，多涉及资源的保存、文件的关闭等。\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "965dada9",
   "metadata": {},
   "source": [
    "1. 无论训练成功、失败还是中途被打断，都确保日志文件被正确关闭，避免数据丢失或文件损坏。\n",
    "2. 确保计算资源在使用完毕后被释放，供其他进程或任务使用。更常见的是使用 with 语句来自动管理这类资源，with 语句本身就隐式地使用了类似 finally 的机制。（with open语句）\n",
    "3. 关闭数据库连接\n",
    "4. 恢复全局状态或配置， 如果程序在运行过程中修改了全局变量或配置文件，在异常处理结束后，需要恢复到之前的状态或配置。\n",
    "5. 模型训练可能非常耗时，如果中途因为各种原因（OOM、手动中断、硬件故障）停止，我们希望记录下中断的状态，方便后续恢复。\n",
    "\n",
    "在ML/DL项目中，由于流程长、资源消耗大、外部依赖多，finally 提供的这种“保证执行”的机制对于构建稳定、可靠的系统至关重要"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "vs",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.18"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
